<template>
  <view class="gomoku-game-container">
    <!-- 头部信息 -->
    <view class="game-header">
      <view class="header-title">五子棋</view>
      <view class="user-info">{{ userName }}</view>
      <view class="game-status">{{ currentPlayer === userId ? '你的回合' : '对方回合' }}</view>
    <view class="game-tip">{{ gameTip }}</view>
  </view>

  <!-- 游戏信息 -->
  <view class="game-info">
    <view class="info-item">
      <view class="info-label">当前回合</view>
      <view class="info-value">{{ currentPlayerPiece }}</view>
    </view>
    <view class="info-item">
      <view class="info-label">游戏时间</view>
      <view class="info-value">{{ gameTime }}s</view>
    </view>
    <view class="info-item">
      <view class="info-label">步数</view>
      <view class="info-value">{{ moveHistory.length }}</view>
    </view>
  </view>

  <!-- 游戏区域 -->
  <view class="game-area">
    <h2 class="game-title"><i class="fa fa-circle-o"></i> 五子棋对战</h2>

    <!-- 玩家列表 -->
    <view class="player-list">
      <view class="player-card" :class="{ 'current': currentPlayer === players[0]?.user_id }">{{ players[0]?.user_name || '等待加入...' }}
        <view class="piece-type"><i class="fa fa-circle-o"></i></view>
      </view>
      <view class="player-card" :class="{ 'current': currentPlayer === players[1]?.user_id }">{{ players[1]?.user_name || '等待加入...' }}
        <view class="piece-type"><i class="fa fa-times"></i></view>
      </view>
    </view>

    <!-- 游戏棋盘 -->
    <view class="game-board">
      <canvas canvas-id="gomokuCanvas" class="game-canvas" @tap="handleCanvasTap"></canvas>
    </view>

    <!-- 控制按钮 -->
    <view class="control-buttons">
      <button class="btn restart-btn" @tap="restartGame">重新开始</button>
      <button class="btn undo-btn" @tap="undoMove" :disabled="moveHistory.length === 0 || gameState.gameOver">悔棋</button>
      <button class="btn back-btn" @tap="backToLobby">返回大厅</button>
    </view>
  </view>

  <!-- 胜利模态框 -->
  <view class="modal-overlay" v-if="showWinModalValue">
    <view class="modal-content">
      <view class="modal-title">游戏结束</view>
      <view class="modal-message">{{ winnerText }} 获胜!</view>
      <view class="modal-buttons">
        <button class="modal-btn new-game-btn" @tap="restartGame">新游戏</button>
        <button class="modal-btn close-btn" @tap="hideWinModal">关闭</button>
      </view>
    </view>
  </view>
  </view>
</template>

<script setup>
import { ref, reactive, onMounted, onUnmounted, computed } from 'vue';
import { CONFIG } from '@/utils/config';
import { createGameConnection, GameType } from '@/utils/websocket-manager';
import { 
  initGamePlayers,
  updatePlayerInfo,
  removePlayer
} from '@/utils/game-utils';
import { getCurrentUserInfo } from '@/utils/auth'


// 游戏状态
const gameState = reactive({
  rows: 15,
  cols: 15,
  cellSize: 30,
  board: [],
  gameOver: false,
  winner: null,
  canvasWidth: 0,
  canvasHeight: 0
});

// 玩家信息
const players = ref([]);
const currentPlayer = ref('');
const userId = ref('');
const userName = ref('');

// 游戏控制
const isReady = ref(false);
const gameTip = ref('等待对手加入...');

// 棋盘相关
const lastMove = ref({ i: -1, j: -1 });

// 计时器相关
let timerInterval = null;
const gameTime = ref(0);

// 悔棋相关
const moveHistory = ref([]);

// 胜利模态框相关
const showWinModalValue = ref(false);
const winnerText = ref('');

// 计算属性
const currentPlayerPiece = computed(() => {
  return currentPlayer.value === players.value[0]?.user_id ? 'black' : 'white';
});

const currentPlayerText = computed(() => {
  const player = players.value.find(p => p.user_id === currentPlayer.value);
  return player ? player.user_name : (currentPlayerPiece.value === 'black' ? '黑棋' : '白棋');
});

const moveCount = computed(() => {
  return moveHistory.value.length;
});

const formattedGameTime = computed(() => {
  const minutes = Math.floor(gameTime.value / 60).toString().padStart(2, '0');
  const seconds = (gameTime.value % 60).toString().padStart(2, '0');
  return `${minutes}:${seconds}`;
});

// WebSocket管理器
let wsManager = null;

/**
 * 初始化WebSocket连接
 */
function initWebSocket() {
  const roomId = uni.getStorageSync('roomId')
  console.log('五子棋游戏初始化WebSocket，房间ID:', roomId)
  
  if (!roomId) {
    console.error('房间ID为空，无法初始化WebSocket')
    uni.showToast({
      title: '房间ID为空',
      icon: 'none',
      duration: 2000
    })
    return
  }
  
  if (!userId.value || !userName.value) {
    console.error('用户信息为空，无法初始化WebSocket')
    uni.showToast({
      title: '用户信息为空',
      icon: 'none',
      duration: 2000
    })
    return
  }
  
  try {
    wsManager = createGameConnection(GameType.GOMOKU, roomId, {
      onOpen: () => {
        console.log('五子棋WebSocket连接成功')
        // 重置防止重连标志，允许正常重连
        wsManager.resetPreventReconnect()
        uni.showToast({
          title: '连接成功',
          icon: 'success',
          duration: 1000
        })
        
        // 连接成功后立即发送加入消息
        const joinMessage = {
          type: 1, // JOIN
          user_id: userId.value,
          user_name: userName.value,
          room_id: String(roomId),
          content: `${userName.value} 加入了游戏房间`,
          time: Math.floor(Date.now() / 1000)
        }
        wsManager.send(joinMessage)
      },
      onJoin: updatePlayerList,
      onLeave: updatePlayerList,
      onReady: updatePlayerReadyStatus,
      onGameOp: handleGameOperation,
      onGameState: updateGameState,
      onGameStart: handleGameStart,
      onGameEnd: handleGameEnd,
      onUserListUpdate: handleUserListUpdate,
      onRoomUserCount: handleRoomUserCount,
      onError: (error) => {
        console.error('五子棋WebSocket连接错误:', error)
        uni.showToast({
          title: '连接失败',
          icon: 'none',
          duration: 2000
        })
      }
    });
    
    console.log('WebSocket管理器创建完成，开始连接')
    wsManager.connect().then(() => {
      console.log('WebSocket连接成功')
    }).catch((error) => {
      console.error('WebSocket连接失败:', error)
    })
  } catch (error) {
    console.error('创建WebSocket管理器失败:', error)
  }
}

/**
 * 更新玩家列表
 */
function updatePlayerList(message) {
  console.log('更新玩家列表:', message)
  
  // 如果是加入消息，添加到玩家列表
  if (message.type === 1 || message.type === 'join') {
    const newPlayer = {
      user_id: message.user_id,
      user_name: message.user_name,
      ready: false
    }
    
    // 检查是否已存在
    const existingIndex = players.value.findIndex(p => p.user_id === newPlayer.user_id)
    if (existingIndex === -1) {
      players.value.push(newPlayer)
      console.log('添加新玩家:', newPlayer)
    } else {
      players.value[existingIndex] = newPlayer
      console.log('更新玩家信息:', newPlayer)
    }
  }
  // 如果是离开消息，从玩家列表中移除
  else if (message.type === 2 || message.type === 'leave') {
    const playerIndex = players.value.findIndex(p => p.user_id === message.user_id)
    if (playerIndex !== -1) {
      const removedPlayer = players.value.splice(playerIndex, 1)[0]
      console.log('移除玩家:', removedPlayer)
    }
  }
  
  // 强制触发响应式更新
  players.value = [...players.value]
  
  console.log('更新后的玩家列表:', players.value)
  
  // 更新游戏提示
  if (players.value.length === 1) {
    gameTip.value = '等待其他玩家加入...'
  } else if (players.value.length >= 2) {
    gameTip.value = '玩家已就位，准备开始游戏！'
  } else {
    gameTip.value = '等待玩家加入...'
  }
}

/**
 * 更新玩家准备状态
 */
function updatePlayerReadyStatus(message) {
  console.log('更新玩家准备状态:', message);
  
  if (message.userId && message.data) {
    const player = players.value.find(p => p.user_id === message.userId);
    if (player) {
      player.ready = message.data.ready || false;
    }
  }
}

/**
 * 处理游戏操作
 */
function handleGameOperation(message) {
  console.log('处理游戏操作:', message)
  // 处理五子棋游戏操作
}

/**
 * 处理游戏开始
 */
function handleGameStart(message) {
  console.log('游戏开始:', message);
  gameTip.value = '游戏开始！';
  isReady.value = true;
}

/**
 * 更新游戏状态
 */
function updateGameState(message) {
  console.log('更新游戏状态:', message)
  // 处理游戏状态更新
}

/**
 * 处理游戏结束
 */
function handleGameEnd(message) {
  console.log('游戏结束:', message)
  // 处理游戏结束
}

/**
 * 处理用户列表更新
 */
function handleUserListUpdate(message) {
  console.log('收到用户列表更新:', message)
  
  try {
    let userList = [];
    
    // 处理不同的消息格式
    if (message.content) {
      if (typeof message.content === 'string') {
        userList = JSON.parse(message.content);
      } else if (Array.isArray(message.content)) {
        userList = message.content;
      }
    } else if (message.data && Array.isArray(message.data)) {
      userList = message.data;
    }
    
    console.log('解析后的用户列表:', userList);
    
    // 更新玩家列表
    players.value = userList.map(user => ({
      user_id: user.user_id || user.userId,
      user_name: user.user_name || user.userName,
      ready: user.ready || false
    }));
    
    // 强制触发响应式更新
    players.value = [...players.value];
    
    console.log('更新后的玩家列表:', players.value);
    
    // 更新游戏提示
    if (players.value.length === 1) {
      gameTip.value = '等待其他玩家加入...';
    } else if (players.value.length >= 2) {
      gameTip.value = '玩家已就位，准备开始游戏！';
    } else {
      gameTip.value = '等待玩家加入...';
    }
    
    // 显示用户列表更新提示
    uni.showToast({
      title: `房间用户更新: ${players.value.length}人`,
      icon: 'none',
      duration: 1500
    });
  } catch (error) {
    console.error('解析用户列表失败:', error);
    console.error('原始消息:', message);
  }
}

/**
 * 处理房间人数更新
 */
function handleRoomUserCount(message) {
  console.log('收到房间人数更新:', message)
  
  if (message.data) {
    const { user_count, max_users } = message.data;
    console.log(`房间人数: ${user_count}/${max_users}`);
    
    // 更新游戏提示
    if (user_count === 1) {
      gameTip.value = '等待其他玩家加入...';
    } else if (user_count >= 2) {
      gameTip.value = '玩家已就位，准备开始游戏！';
    }
    
    // 强制触发响应式更新
    gameTip.value = gameTip.value;
  }
}

/**
 * 初始化棋盘
 */
function initBoard() {
  // 初始化棋盘数组
  gameState.board = Array(gameState.rows).fill().map(() => Array(gameState.cols).fill(null));
  
  // 计算画布尺寸
  gameState.canvasWidth = gameState.cols * gameState.cellSize;
  gameState.canvasHeight = gameState.rows * gameState.cellSize;
  
  // 初始化游戏状态
  gameState.gameOver = false;
  gameState.winner = null;
  lastMove.value = { i: -1, j: -1 };
  
  // 初始化计时器和历史记录
  gameTime.value = 0;
  moveHistory.value = [];
  
  // 启动计时器
  startTimer();
  
  // 渲染棋盘
  renderBoard();
}

/**
 * 渲染棋盘
 */
function renderBoard() {
  const ctx = uni.createCanvasContext('gomokuCanvas');
  
  // 绘制棋盘背景
  ctx.setFillStyle('#deb887');
  ctx.fillRect(0, 0, gameState.canvasWidth, gameState.canvasHeight);
  
  // 绘制网格线
  ctx.setStrokeStyle('#8b4513');
  ctx.setLineWidth(1);
  
  // 绘制竖线
  for (let i = 0; i < gameState.cols; i++) {
    const x = i * gameState.cellSize + gameState.cellSize / 2;
    ctx.beginPath();
    ctx.moveTo(x, gameState.cellSize / 2);
    ctx.lineTo(x, gameState.canvasHeight - gameState.cellSize / 2);
    ctx.stroke();
  }
  
  // 绘制横线
  for (let j = 0; j < gameState.rows; j++) {
    const y = j * gameState.cellSize + gameState.cellSize / 2;
    ctx.beginPath();
    ctx.moveTo(gameState.cellSize / 2, y);
    ctx.lineTo(gameState.canvasWidth - gameState.cellSize / 2, y);
    ctx.stroke();
  }
  
  // 绘制天元和星位
  ctx.setFillStyle('#000');
  const positions = [
    [3, 3], [3, 7], [3, 11],
    [7, 3], [7, 7], [7, 11],
    [11, 3], [11, 7], [11, 11]
  ];
  
  positions.forEach(([row, col]) => {
    const x = col * gameState.cellSize + gameState.cellSize / 2;
    const y = row * gameState.cellSize + gameState.cellSize / 2;
    ctx.beginPath();
    ctx.arc(x, y, 3, 0, 2 * Math.PI);
    ctx.fill();
  });
  
  // 绘制棋子
  for (let i = 0; i < gameState.rows; i++) {
    for (let j = 0; j < gameState.cols; j++) {
      if (gameState.board[i][j]) {
        const x = j * gameState.cellSize + gameState.cellSize / 2;
        const y = i * gameState.cellSize + gameState.cellSize / 2;
        const radius = gameState.cellSize / 2 - 2;
        
        if (gameState.board[i][j] === 'black') {
          ctx.setFillStyle('#000');
        } else {
          ctx.setFillStyle('#fff');
          ctx.setStrokeStyle('#000');
          ctx.setLineWidth(1);
        }
        
        // 绘制棋子阴影
        ctx.beginPath();
        ctx.arc(x + 1, y + 1, radius, 0, 2 * Math.PI);
        ctx.setFillStyle('rgba(0, 0, 0, 0.3)');
        ctx.fill();
        
                // 绘制棋子
        ctx.beginPath();
        ctx.arc(x, y, radius, 0, 2 * Math.PI);
        ctx.fill();
        
        if (gameState.board[i][j] === 'white') {
          ctx.stroke();
        }
      }
    }
  }
  
  // 绘制最后一步的标记
  if (lastMove.value.i >= 0 && lastMove.value.j >= 0) {
    const x = lastMove.value.j * gameState.cellSize + gameState.cellSize / 2;
    const y = lastMove.value.i * gameState.cellSize + gameState.cellSize / 2;
    const radius = 4;
    
    ctx.setFillStyle('#ff0000');
    ctx.beginPath();
    ctx.arc(x, y, radius, 0, 2 * Math.PI);
    ctx.fill();
  }
  
  // 绘制到画布
  ctx.draw();
}



/**
 * 更新游戏时间
 */
function updateGameTime() {
  gameTime.value++;
}

/**
 * 开始计时
 */
function startTimer() {
  clearInterval(timerInterval);
  timerInterval = setInterval(updateGameTime, 1000);
}

/**
 * 停止计时
 */
function stopTimer() {
  clearInterval(timerInterval);
}

/**
 * 显示胜利模态框
 */
function showWinModal(winner) {
  gameState.gameOver = true;
  stopTimer();
  
  const winnerPlayer = players.value.find(p => p.user_id === winner);
  winnerText.value = winnerPlayer ? winnerPlayer.user_name : (gameState.board[lastMove.value.i][lastMove.value.j] === 'black' ? '黑棋' : '白棋');
  showWinModalValue.value = true;
}

/**
 * 隐藏胜利模态框
 */
function hideWinModal() {
  showWinModalValue.value = false;
}

/**
 * 处理棋盘点击
 */
function handleCanvasTap(e) {
  if (gameState.gameOver || currentPlayer.value !== userId.value || !isReady.value) {
    return;
  }

  const { x, y } = e.detail;
  const canvasRect = uni.createSelectorQuery().select('.game-canvas').boundingClientRect();

  canvasRect.exec(rects => {
    if (rects && rects[0]) {
      const rect = rects[0];
      const canvasX = x - rect.left;
      const canvasY = y - rect.top;

      // 计算点击的行列
      const j = Math.round((canvasX - gameState.cellSize / 2) / gameState.cellSize);
      const i = Math.round((canvasY - gameState.cellSize / 2) / gameState.cellSize);

      // 检查是否在棋盘范围内且为空
      if (i >= 0 && i < gameState.rows && j >= 0 && j < gameState.cols && !gameState.board[i][j]) {
        // 落子
        const pieceType = currentPlayer.value === players.value[0]?.user_id ? 'black' : 'white';
        gameState.board[i][j] = pieceType;
        lastMove.value = { i, j };
        moveHistory.value.push({ i, j, player: currentPlayer.value, pieceType });

        // 检查是否获胜
        if (checkWin(i, j, pieceType)) {
          gameState.winner = currentPlayer.value;
          gameTip.value = `${players.value.find(p => p.user_id === currentPlayer.value)?.user_name} 获胜！`;
          showWinModal(currentPlayer.value);
        } else {
          // 检查是否平局
          if (checkDraw()) {
            gameState.gameOver = true;
            stopTimer();
            gameTip.value = '游戏结束 - 平局!';
            return;
          }
          
          // 切换玩家
          currentPlayer.value = currentPlayer.value === players.value[0]?.user_id ? players.value[1]?.user_id : players.value[0]?.user_id;
          gameTip.value = currentPlayer.value === userId.value ? '你的回合' : '对方回合';
        }

        // 渲染棋盘
        renderBoard();

        // 发送落子信息到服务器
        if (wsManager && wsManager.getConnected()) {
          const message = {
            type: 6, // MessageTypeGameOp
            user_id: userId.value,
            user_name: userName.value,
            room_id: uni.getStorageSync('roomId'),
            time: Math.floor(Date.now() / 1000),
            data: {
              row: i,
              col: j,
              pieceType: pieceType
            }
          };
          wsManager.send(message);
        }
      }
    }
  });
}

/**
 * 检查是否获胜
 */
function checkWin(i, j, pieceType) {
  const directions = [
    [1, 0],   // 水平
    [0, 1],   // 垂直
    [1, 1],   // 对角线
    [1, -1]   // 反对角线
  ];

  for (const [dx, dy] of directions) {
    let count = 1;  // 当前位置已经有一个棋子

    // 正向检查
    for (let step = 1; step < 5; step++) {
      const ni = i + step * dy;
      const nj = j + step * dx;

      if (ni >= 0 && ni < gameState.rows && nj >= 0 && nj < gameState.cols && gameState.board[ni][nj] === pieceType) {
        count++;
      } else {
        break;
      }
    }

    // 反向检查
    for (let step = 1; step < 5; step++) {
      const ni = i - step * dy;
      const nj = j - step * dx;

      if (ni >= 0 && ni < gameState.rows && nj >= 0 && nj < gameState.cols && gameState.board[ni][nj] === pieceType) {
        count++;
      } else {
        break;
      }
    }

    if (count >= 5) {
      return true;
    }
  }

  return false;
}

/**
 * 检查平局
 */
function checkDraw() {
  for (let i = 0; i < gameState.rows; i++) {
    for (let j = 0; j < gameState.cols; j++) {
      if (!gameState.board[i][j]) {
        return false; // 还有空位，不是平局
      }
    }
  }
  return true; // 棋盘已满，平局
}

/**
 * 悔棋
 */
function undoMove() {
  if (moveHistory.value.length === 0 || gameState.gameOver) {
    return;
  }

  const lastMove = moveHistory.value.pop();
  gameState.board[lastMove.i][lastMove.j] = null;
  currentPlayer.value = lastMove.player; // 回到上一个玩家
  gameTip.value = currentPlayer.value === userId.value ? '你的回合' : '对方回合';

  // 更新最后一步记录
  if (moveHistory.value.length > 0) {
    const prevMove = moveHistory.value[moveHistory.value.length - 1];
    lastMove.value = { i: prevMove.i, j: prevMove.j };
  } else {
    lastMove.value = { i: -1, j: -1 };
  }

  renderBoard();
}

/**
 * 重新开始游戏
 */
function restartGame() {
  initBoard();
  hideWinModal();
}

/**
 * 切换准备状态
 */
function toggleReadyStatus() {
  isReady.value = !isReady.value;
  gameTip.value = isReady.value ? '已准备' : '未准备';
  
  // 发送WebSocket消息通知其他玩家
  if (wsManager && wsManager.getConnected()) {
    const message = {
      type: 4, // MessageTypeReady
      user_id: userId.value,
      user_name: userName.value,
      room_id: uni.getStorageSync('roomId'),
      time: Math.floor(Date.now() / 1000),
      data: {
        ready: isReady.value
      }
    };
    wsManager.send(message);
  }
}

/**
 * 返回游戏大厅
 */
function backToLobby() {
  console.log('=== backToLobby 被调用 ===')
  
  // 发送离开房间消息
  if (wsManager && wsManager.getConnected()) {
    console.log('backToLobby: 发送离开房间消息')
    try {
      const leaveMessage = {
        type: 2, // LEAVE
        user_id: userId.value,
        user_name: userName.value,
        room_id: uni.getStorageSync('roomId'),
        content: `${userName.value} 离开了游戏房间`,
        time: Math.floor(Date.now() / 1000)
      }
      wsManager.send(leaveMessage)
      
      // 等待消息发送完成后再关闭连接
      setTimeout(() => {
        closeWebSocketConnection()
      }, 200) // 增加延迟确保消息发送
    } catch (error) {
      console.error('发送离开消息失败:', error)
      closeWebSocketConnection()
    }
  } else {
    closeWebSocketConnection()
  }
}

function closeWebSocketConnection() {
  // 强制关闭WebSocket连接
  if (wsManager) {
    console.log('backToLobby: 强制关闭WebSocket连接')
    try {
      wsManager.close();
    } catch (error) {
      console.error('关闭WebSocket连接时出错:', error)
    }
    wsManager = null;
  }

  // 清除房间ID和游戏状态
  uni.removeStorageSync('roomId')
  
  // 重置游戏状态
  gameState.value = {
    board: Array(15).fill().map(() => Array(15).fill('')),
    currentPlayer: 'black',
    winner: null,
    gameStarted: false,
    gameOver: false,
    lastMove: null
  }
  
  players.value = []
  gameTip.value = '等待玩家加入...'

  // 导航回游戏空间
  console.log('backToLobby: 导航回游戏空间')
  uni.navigateBack();
}

// 生命周期钩子
onMounted(() => {
  // 初始化棋盘
  initBoard();
  
  // 获取用户信息和房间ID
  const userInfo = getCurrentUserInfo();
  userId.value = userInfo?.userId || 'user123';
  userName.value = userInfo?.userName || '玩家1';
  const roomId = uni.getStorageSync('roomId') || 'room456';
  
  // 初始化玩家列表
  players.value = initGamePlayers(userId.value, userName.value, 2);
  
  currentPlayer.value = players.value[0].user_id;
  gameTip.value = currentPlayer.value === userId.value ? '你的回合' : '对方回合';
  
  // 初始化WebSocket连接
  initWebSocket();
});

onUnmounted(() => {
  // 清理游戏资源
  if (wsManager) {
    wsManager.close();
  }
});
</script>

<style>
@import './gomoku.css';
</style>